/*
 * Reversi 1.1.0
 * par Brian Ravenet et Paul Massiot
 * Classe Plateau
 */
package Jeu;

import java.util.ArrayList;
/**
 * Cette classe permet d'instancier un plateau de Jeu.
 * @author Brian Ravenet
 * @author Paul Massiot
 */
public class Plateau {
/**
 * La matrice qui représente en mémoire le plateau de Jeu.
 */
    public Case plato[][];
/**
 * Le constructeur sans paramètre de Plateau. Celui-ci initialise toutes les
 * cases à VIDE sauf les quatre du milieu.
 */
    public Plateau() {
        super();
        this.plato = new Case[8][8];
        for(int i = 0; i < 8; i++){
            for(int j = 0; j < 8; j++){
                this.plato[i][j] = new Case();
            }
        }
        this.plato[3][3].valeur = Occupation.BLANC;
        this.plato[4][4].valeur = Occupation.BLANC;
        this.plato[3][4].valeur = Occupation.NOIR;
        this.plato[4][3].valeur = Occupation.NOIR;
    }
    /**
     * Ceci est le constructeur par recopie
     * @param other le plateau a recopier
     */
    public Plateau(Plateau other){
        super();
        this.plato = new Case[8][8];
        for(int i = 0; i < 8; i++){
            for(int j = 0; j < 8; j++){
                this.plato[i][j] = new Case();
                this.plato[i][j].valeur = other.plato[i][j].valeur;
            }
        }
    }
/**
 * La fonction de Jeu qui sera appelée lorsque l'on cliquera sur une case.
 * @param i la coordonnée de la case en x
 * @param j la coordonnée de la case en y
 * @param c la couleur qui est jouée
 * @return Renvoi 1 si le joueur ne pouvait pas jouer là. 0 sinon.
 */
    public int Joue(Integer i, Integer j, Occupation c) {
        if (this.plato[i][j].valeur != Occupation.VIDE) {
        	System.out.println("ne peut pas jouer ici");
            return 1;
        } else {
            ArrayList<Direction> directions = new ArrayList<Direction>();
            directions = VerifLigne(i, j, c);
            if (!(directions.isEmpty())) {
                for (Direction d : directions) {
                    int x = i + d.x;
                    int y = j + d.y;
                    while (this.plato[x][y].valeur != c) {
                        this.plato[x][y].valeur = c;
                        x += d.x;
                        y += d.y;
                    }
                }
                this.plato[i][j].valeur = c;
                return 0;
            } else {
            	System.out.println("ne peut pas jouer ici");
                return 1;
            }
        }
    }
/**
 * Prédicat qui teste si un joueur peut jouer. Verifie toutes les cases
 * tous les coups possibles.
 * @param c La couleur du joueur.
 * @return Vrai si le joueur peut jouer. Faux sinon.
 */
    public boolean PeutJouer(Occupation c) {
        boolean test = false;
        for (int i = 0; i <= 7; i++) {
            for (int j = 0; j <= 7; j++) {
                if(estCaseVide(i, j)){
                ArrayList<Direction> directions = new ArrayList<Direction>();
                directions = VerifLigne(i, j, c);
                if (!directions.isEmpty()) {
                    test = true;
                    break;
                }
                }
            }
            if (test) {
                break;
            }
        }
        return test;
    }
    /**
     *  Predicat qui verifie que la case en coordonnée i,j est Vide
     * @param i coordonnée en x de la case
     * @param j coordonnée en y de la case
     * @return Vrai si la case est vide
     */
    public boolean estCaseVide(int i,int j){
        return (this.plato[i][j].valeur == Occupation.VIDE);
    }
    /**
     * Cette fonction retourne une liste de coordonnées où le joueur peut jouer.
     * @param c La couleur du joueur
     * @return une liste de coordonnées
     */
    public ArrayList<int[]> OuJouer(Occupation c){
    	ArrayList<int[]> liste = new ArrayList<int[]>();
    	for (int i = 0; i <= 7; i++) {
            for (int j = 0; j <= 7; j++) {
                if(estCaseVide(i, j)){
                ArrayList<Direction> directions = new ArrayList<Direction>();
                directions = VerifLigne(i, j, c);
                if (!directions.isEmpty()) {
                	int[]temp = new int[2];
                	temp[0] = i;
                	temp[1] = j;
                    liste.add(temp);
                }
                }
            }
    	}
    	return liste;
    }
    
     
/**
 * Fonction qui a une case du plateau donnée et à une couleur de jeu, 
 * renvoi la liste des directions dans lesquelles des pions seront retournées.
 * @param i la coordonnée en x de la case
 * @param j la coordonnée en y de la case
 * @param c la couleur de jeu
 * @return La liste des directions jouables.
 */
    public ArrayList<Direction> VerifLigne(Integer i, Integer j, Occupation c) {

        ArrayList<Direction> directions = new ArrayList<Direction>();
        for (int k = i - 1; k <= i + 1; k++) {
            for (int l = j - 1; l <= j + 1; l++) {
                if (!(k < 0 || l < 0 || (k == i && l == j) || k > 7 || l > 7)) {
                    if (!((this.plato[k][l].valeur == Occupation.VIDE) ||
                            this.plato[k][l].valeur == c)) {
                        int x = k - i;
                        int y = l - j;
                        int xprim = k + x;
                        int yprim = l + y;
                        while (xprim <= 7 && yprim <= 7 && xprim >= 0 && yprim >= 0 && this.plato[xprim][yprim].valeur != Occupation.VIDE &&
                                this.plato[xprim][yprim].valeur != c
                                ) {
                            xprim += x;
                            yprim += y;
                        }

                        if (xprim <= 7 && yprim <= 7 && xprim >= 0 && yprim >= 0 &&
                                this.plato[xprim][yprim].valeur == c) {
                            Direction d = new Direction(x, y);
                            directions.add(d);

                        }

                    }

                }

            }
        }
        return directions;
    }
    /**
     * Fonction qui retourne la couleur du joueur qui possède le plus de jetons
     * sur le plateau.
     * @return La couleur la plus présente. VIDE si égalité.
     */
    public Occupation quiALePlus(){
        int joueurB = 0;
        int joueurN = 0;
        for(int i = 0; i < 8; i++){
            for(int j = 0; j < 8; j++){
              if(!(this.plato[i][j].valeur == Occupation.VIDE)){
                  if(this.plato[i][j].valeur == Occupation.BLANC){
                      joueurB++;
                  }
                  else{
                      joueurN++;
                  }
              }  
            }
        }
      if(joueurB > joueurN){
            return Occupation.BLANC;
        }
      else if (joueurB < joueurN){
          return Occupation.NOIR;
      }
      else return Occupation.VIDE;
    }
}

